home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_std / integer.e < prev    next >
Text File  |  2000-03-25  |  10KB  |  386 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://SmallEiffel.loria.fr
  11. --
  12. expanded class INTEGER
  13. --
  14. -- Note: An Eiffel INTEGER is mapped as a C int or as a Java int.
  15. --
  16.  
  17. inherit
  18.    INTEGER_REF
  19.       redefine
  20.          infix "+", infix "-", infix "*", infix "/", infix "\\", 
  21.          infix "//", infix "^", infix "<", infix "<=", infix ">",
  22.          infix ">=", prefix "-", prefix "+", hash_code, 
  23.          one, zero, out_in_tagged_out_memory, fill_tagged_out_memory
  24.       end;
  25.  
  26. feature 
  27.    
  28.    one: INTEGER is 1;
  29.  
  30.    zero: INTEGER is 0;
  31.  
  32.    infix "+" (other: INTEGER): INTEGER is
  33.       external "SmallEiffel"
  34.       end;
  35.    
  36.    infix "-" (other: INTEGER): INTEGER is
  37.       external "SmallEiffel"
  38.       end;
  39.  
  40.    infix "*" (other: INTEGER): INTEGER is
  41.       external "SmallEiffel"
  42.       end;
  43.  
  44.    infix "/" (other: INTEGER): DOUBLE is
  45.       external "SmallEiffel"
  46.       end;
  47.  
  48.    infix "//" (other: INTEGER): INTEGER is
  49.       external "SmallEiffel"
  50.       end;
  51.  
  52.    infix "\\" (other: INTEGER): INTEGER is
  53.       external "SmallEiffel"
  54.       end;
  55.    
  56.    infix "^" (exp: INTEGER): INTEGER is
  57.       do
  58.          if exp = 0 then
  59.             Result := 1;
  60.          elseif exp \\ 2 = 0 then
  61.             Result := (Current * Current) ^ (exp // 2);
  62.          else
  63.             Result := Current * (Current ^ (exp - 1));
  64.          end;
  65.       end;
  66.    
  67.    abs: INTEGER is
  68.          -- Absolute value of `Current'.
  69.       do
  70.          if Current < 0 then
  71.             Result := -Current;
  72.          else
  73.             Result := Current;
  74.          end;
  75.       end;
  76.          
  77.    infix "<" (other: INTEGER): BOOLEAN is
  78.          -- Is 'Current' strictly less than 'other'?
  79.       external "SmallEiffel"
  80.       end;
  81.  
  82.    infix "<=" (other: INTEGER): BOOLEAN is
  83.          -- Is 'Current' less or equal 'other'?
  84.       external "SmallEiffel"
  85.       end;
  86.  
  87.    infix ">" (other: INTEGER): BOOLEAN is
  88.          -- Is 'Current' strictly greater than 'other'?
  89.       external "SmallEiffel"
  90.       end;
  91.  
  92.    infix ">=" (other: INTEGER): BOOLEAN is
  93.          -- Is 'Current' greater or equal than 'other'?
  94.       external "SmallEiffel"
  95.       end;
  96.  
  97.    prefix "+": INTEGER is
  98.       do
  99.          Result := Current
  100.       end;
  101.  
  102.    prefix "-": INTEGER is
  103.       external "SmallEiffel"
  104.       end;
  105.    
  106.    odd: BOOLEAN is
  107.          -- Is odd ?
  108.       do
  109.          Result := (Current \\ 2) = 1;
  110.       end;
  111.  
  112.    even: BOOLEAN is
  113.          -- Is even ?
  114.       do
  115.          Result := (Current \\ 2) = 0;
  116.       end;
  117.  
  118.    sqrt: DOUBLE is
  119.          -- Compute the square routine.
  120.       do
  121.          Result := to_double.sqrt;
  122.       end;
  123.  
  124.    log: DOUBLE is
  125.          -- (ANSI C log).
  126.       do
  127.          Result := to_double.log;
  128.       end;
  129.  
  130.    log10: DOUBLE is
  131.          -- (ANSI C log10).
  132.       do
  133.          Result := to_double.log10;
  134.       end;
  135.  
  136.    gcd(other: INTEGER): INTEGER is
  137.          -- Great Common Divisor of `Current' and `other'.
  138.       require
  139.          Current >= 0;
  140.          other >= 0;
  141.       do
  142.          if other = 0 then 
  143.             Result := Current
  144.          else
  145.             Result := other.gcd(Current \\ other);
  146.          end;    
  147.       ensure
  148.          Result = other.gcd(Current);
  149.       end;
  150.    
  151. feature -- Conversions :
  152.    
  153.    to_real: REAL is
  154.       do
  155.          Result := Current;
  156.       end;
  157.    
  158.    to_double: DOUBLE is
  159.       do
  160.          Result := Current;
  161.       end;
  162.    
  163.    to_string: STRING is
  164.          -- Convert the decimal view of `Current' into a new allocated STRING.
  165.          -- For example, if `Current' is -1 the new STRING is "-1".
  166.          -- Note: see also `append_in' to save memory.
  167.       do
  168.          !!Result.make(0);
  169.          append_in(Result);
  170.       end; 
  171.  
  172.    to_boolean: BOOLEAN is
  173.          -- Return false for 0, otherwise true.
  174.       do
  175.          Result := Current /= 0;
  176.       ensure 
  177.          Result = (Current /= 0)
  178.       end;
  179.  
  180.    to_bit: BIT Integer_bits is
  181.          -- Portable BIT_N conversion.
  182.       external "SmallEiffel"
  183.       end;
  184.  
  185.    append_in(buffer: STRING) is
  186.          -- Append in the `buffer' the equivalent of `to_string'. No new STRING 
  187.          -- creation during the process.
  188.       require
  189.          buffer /= Void
  190.       local
  191.          val, i: INTEGER;
  192.       do
  193.          if Current = 0 then
  194.             buffer.extend('0');
  195.          else
  196.             if Current > 0 then
  197.                from
  198.                   i := buffer.count + 1;
  199.                   val := Current;
  200.                until
  201.                   val = 0
  202.                loop
  203.                   buffer.extend((val \\ 10).digit);
  204.                   val := val // 10;
  205.                end;
  206.             else
  207.                buffer.extend('-');
  208.                from
  209.                   i := buffer.count + 1;
  210.                   val := Current;
  211.                until
  212.                   val = 0
  213.                loop
  214.                   buffer.extend((-(val \\ 10)).digit);
  215.                   val := val // 10;
  216.                end;
  217.             end;
  218.             from  
  219.                val := buffer.count;
  220.             until
  221.                i >= val
  222.             loop
  223.                buffer.swap(i,val);
  224.                val := val - 1;
  225.                i := i + 1;
  226.             end;
  227.          end;
  228.       end; 
  229.    
  230.    to_string_format(s: INTEGER): STRING is
  231.          -- Same as `to_string' but the result is on `s' character and the 
  232.          -- number is right aligned. 
  233.          -- Note: see `append_in_format' to save memory.
  234.       require
  235.          to_string.count <= s;
  236.       do
  237.          from  
  238.             tmp_string.clear;
  239.             append_in(tmp_string);
  240.          until
  241.             tmp_string.count >= s
  242.          loop
  243.             tmp_string.add_first(' ');
  244.          end;
  245.          Result := tmp_string.twin;
  246.       ensure
  247.          Result.count = s;
  248.       end; 
  249.  
  250.    append_in_format(str: STRING; s: INTEGER) is
  251.          -- Append the equivalent of `to_string_format' at the end of 
  252.          -- `str'. Thus you can save memory because no other
  253.          -- STRING is allocate for the job.
  254.       do
  255.          from
  256.             tmp_string.clear;
  257.             append_in(tmp_string);
  258.          until
  259.             tmp_string.count >= s
  260.          loop
  261.             tmp_string.add_first(' ');
  262.          end;
  263.          str.append(tmp_string);
  264.       ensure
  265.          str.count >= (old str.count) + s;
  266.       end;
  267.    
  268.    decimal_digit, digit: CHARACTER is
  269.          -- Gives the corresponding CHARACTER for range 0..9.
  270.       require
  271.          in_range(0,9)
  272.       do
  273.          Result := (Current + ('0').code).to_character;
  274.       ensure
  275.          ("0123456789").has(Result);
  276.          Result.value = Current
  277.       end;
  278.       
  279.    hexadecimal_digit: CHARACTER is
  280.          -- Gives the corresponding CHARACTER for range 0..15.
  281.       require
  282.          in_range(0,15)
  283.       do
  284.          if Current <= 9 then
  285.             Result := digit;
  286.          else
  287.             Result := (('A').code + (Current - 10)).to_character;
  288.          end;
  289.       ensure
  290.          ("0123456789ABCDEF").has(Result)
  291.       end;
  292.  
  293.    to_character: CHARACTER is
  294.          -- Return the coresponding ASCII character.
  295.       require
  296.          Current >= 0;
  297.       external "SmallEiffel"
  298.       end;
  299.    
  300.    to_octal: INTEGER is
  301.          -- Gives coresponding octal value.
  302.       do
  303.          if Current = 0 then
  304.          elseif Current < 0 then
  305.             Result := -((-Current).to_octal);
  306.          else
  307.             from  
  308.                tmp_string.clear;
  309.                Result := Current;
  310.             until
  311.                Result = 0
  312.             loop
  313.                tmp_string.extend((Result \\ 8).digit);
  314.                Result := Result // 8;
  315.             end;
  316.             tmp_string.reverse;
  317.             Result := tmp_string.to_integer;
  318.          end;
  319.       end;
  320.    
  321.    to_hexadecimal: STRING is
  322.          -- Convert the hexadecimal view of `Current' into a new allocated 
  323.          -- STRING. For example, if `Current' is -1 the new STRING is "FFFF" 
  324.          -- on a 32 bit machine.
  325.          -- Note: see also `to_hexadecimal_in' to save memory.
  326.       do
  327.          tmp_string.clear;
  328.          to_hexadecimal_in(tmp_string);
  329.          Result := tmp_string.twin;
  330.       ensure
  331.          Result.count = Integer_bits / 4
  332.       end;
  333.  
  334.    to_hexadecimal_in(buffer: STRING) is
  335.          -- Append in `buffer' the equivalent of `to_hexadecimal'. No new STRING 
  336.          -- creation during the process.
  337.       local
  338.          one_digit, times, index: INTEGER;
  339.          value: BIT Integer_bits;
  340.       do
  341.          from
  342.             value := to_bit;
  343.             times := Integer_bits // 4;
  344.             index := buffer.count + times;
  345.             buffer.extend_multiple(' ',times);
  346.          until
  347.             times = 0
  348.          loop
  349.             one_digit := (value and 1111B).to_integer;
  350.             buffer.put(one_digit.hexadecimal_digit,index);
  351.             index := index - 1;
  352.             value := value @>> 4;
  353.             times := times - 1;
  354.          end;
  355.       ensure
  356.          buffer.count = old buffer.count + Integer_bits / 4
  357.       end;
  358.       
  359. feature -- Object Printing :
  360.  
  361.    out_in_tagged_out_memory, fill_tagged_out_memory is
  362.       do
  363.          Current.append_in(tagged_out_memory);
  364.       end;
  365.  
  366. feature -- Hashing :
  367.    
  368.    hash_code: INTEGER is
  369.       do
  370.          if Current < 0 then
  371.             Result := -(Current + 1);
  372.          else
  373.             Result := Current;
  374.          end
  375.       end;
  376.  
  377. feature {NONE}
  378.    
  379.    tmp_string: STRING is 
  380.       once
  381.          !!Result.make(128);
  382.       end;
  383.          
  384. end -- INTEGER
  385.  
  386.